package Getopt::Moose::Parser;

use if $ENV{DEBUG} => 'Smart::Comments';

use Moose;

use Getopt::Long;
use MooseX::Getopt::OptionTypeMap;


# Special configuration for parser
has 'config' => (
    is => 'rw',
    isa => 'ArrayRef[Str]',
    auto_deref => 1,
    default => sub { [] },
);


sub get_options {
    my $self = shift;
    my ($getopt, @attrs) = @_;

    $self->throw_error('First argument is not a Getopt::Moose')
        unless $getopt->isa('Getopt::Moose');

    my $options = $getopt->options;
    my @opts;

    foreach my $attr (@attrs) {
        my $name = $attr->name;

        my $opt_string = $attr->has_cmd_name ? $attr->cmd_name : $name;
        
        if ($attr->has_cmd_aliases && scalar @{ $attr->cmd_aliases }) {
            $opt_string .= '|' . join '|', @{ $attr->cmd_aliases };
        }

        if ($attr->has_cmd_type || $attr->has_type_constraint) {
            my $type = $attr->has_cmd_type ? $attr->cmd_type : $attr->type_constraint;
            if (MooseX::Getopt::OptionTypeMap->has_option_type($type)) {
                $opt_string .= MooseX::Getopt::OptionTypeMap->get_option_type($type)
            }
        }

        $options->{$name} = undef;
        push @opts, $opt_string => \$options->{$name};
    }

    ### Getopt::Moose::Parser::init_options @opts : @opts

    GETOPT: {
        my $parser = new Getopt::Long::Parser;
        $parser->configure( $self->config );

        local @ARGV = $getopt->argv;
        ### Getopt::Moose::Parser::init_options @ARGV : @ARGV

        local $SIG{__WARN__} = sub { return warn @_ if $_[0]=~/^\###/; my $warning = $getopt->warning; $warning .= $_[0]; $getopt->warning( $warning ) };

        my $status = $parser->getoptions( @opts );
        $getopt->status( $status );

        my $argv_extra = \@ARGV;
        $getopt->argv_extra( $argv_extra );
    }

    ### Getopt::Moose::Parser::init_options @opts : @opts

    ### Getopt::Moose::Parser::init_options $options : $options
    return $options;
}


1;
